﻿using System;

namespace Aeon.Emulator.Instructions.FPU
{
    internal static class Fdiv
    {
        [Opcode("D8/6 mf32", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideST032(VirtualMachine vm, float value)
        {
            DivideST064(vm, value);
        }

        [Opcode("DC/6 mf64|D8F0+ st|DCF8 st0", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideST064(VirtualMachine vm, double value)
        {
            vm.Processor.FPU.ST0 /= value;
        }

        [Opcode("DCF9", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST1(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(1);
            vm.Processor.FPU.SetRegisterValue(1, value / vm.Processor.FPU.ST0);
        }
        [Opcode("DCFA", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST2(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(2);
            vm.Processor.FPU.SetRegisterValue(2, value / vm.Processor.FPU.ST0);
        }
        [Opcode("DCFB", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST3(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(3);
            vm.Processor.FPU.SetRegisterValue(3, value / vm.Processor.FPU.ST0);
        }
        [Opcode("DCFC", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST4(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(4);
            vm.Processor.FPU.SetRegisterValue(4, value / vm.Processor.FPU.ST0);
        }
        [Opcode("DCFD", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST5(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(5);
            vm.Processor.FPU.SetRegisterValue(5, value / vm.Processor.FPU.ST0);
        }
        [Opcode("DCFE", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST6(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(6);
            vm.Processor.FPU.SetRegisterValue(6, value / vm.Processor.FPU.ST0);
        }
        [Opcode("DCFF", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST7(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(7);
            vm.Processor.FPU.SetRegisterValue(7, value / vm.Processor.FPU.ST0);
        }
    }

    internal static class Fdivp
    {
        [Opcode("DEF8", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST0(VirtualMachine vm)
        {
            throw new InvalidOperationException();
        }
        [Opcode("DEF9", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST1(VirtualMachine vm)
        {
            Fdiv.DivideToST1(vm);
            vm.Processor.FPU.Pop();
        }
        [Opcode("DEFA", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST2(VirtualMachine vm)
        {
            Fdiv.DivideToST2(vm);
            vm.Processor.FPU.Pop();
        }
        [Opcode("DEFB", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST3(VirtualMachine vm)
        {
            Fdiv.DivideToST3(vm);
            vm.Processor.FPU.Pop();
        }
        [Opcode("DEFC", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST4(VirtualMachine vm)
        {
            Fdiv.DivideToST4(vm);
            vm.Processor.FPU.Pop();
        }
        [Opcode("DEFD", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST5(VirtualMachine vm)
        {
            Fdiv.DivideToST5(vm);
            vm.Processor.FPU.Pop();
        }
        [Opcode("DEFE", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST6(VirtualMachine vm)
        {
            Fdiv.DivideToST6(vm);
            vm.Processor.FPU.Pop();
        }
        [Opcode("DEFF", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void DivideToST7(VirtualMachine vm)
        {
            Fdiv.DivideToST7(vm);
            vm.Processor.FPU.Pop();
        }
    }
}
